package net.xxcl.exam.controller;

import net.xxcl.exam.pojo.*;
import net.xxcl.exam.service.PaperService;
import net.xxcl.exam.service.ScoreService;
import net.xxcl.exam.util.RealIpUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: 夏汛
 * Date: 11-12-26
 * Time: 下午12:24
 */
@Controller
@RequestMapping("/ks")
public class KsController {

    @Autowired
    private ScoreService scoreService;
    @Autowired
    private PaperService paperService;

    /**
     * 开始考试
     * @param paperid
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/startKs")
    public @ResponseBody Map<String,Object> startKs(@RequestParam("paperid") Integer paperid,
                                                    HttpServletRequest request,HttpServletResponse response){
        //获取应用上下文，即application对象
        ServletContext sct = request.getSession().getServletContext();
        Student student = (Student)request.getSession().getAttribute("student");
        Map<String,Object> responseMap = new HashMap<String, Object>();
        try{
            Paper paper = paperService.selectByPrimaryKey(paperid);
            if(paper.getState()!=2){
                responseMap.put("info","考试还未开始！");
                return responseMap;
            };
            Score score = new Score();
            score.setStuid(student.getId());
            score.setPaperid(paperid);
            if((score=scoreService.selectByPrimaryKey(score))==null){
                responseMap.put("info","你不能参加该考试！");
                return responseMap;
              } else if(score.getState()==3 || score.getState()==4){
                       responseMap.put("info","你已经参加过考试！");
                return responseMap;
            } else {
                //获取试题排序
                responseMap.put("question",score.getQuestion());
                //如果存在实时保存的客观题答案，读取出来
                if(score.getKgtda()!=null){
                    responseMap.put("myAnswer",score.getKgtda());
                } else {
                    responseMap.put("myAnswer","");
                }
                //从application对象获取试题，若无则添加进application对象
                if(sct.getAttribute("paper"+paperid)!=null){
                    responseMap.put("all",sct.getAttribute("paper"+paperid));
                } else {
                    List<Question> questions = scoreService.getPaperObject(paperid);
                    sct.setAttribute("paper"+paperid,questions);
                    responseMap.put("all",questions);
                }
                //获取考试剩余时间
                if(score.getState()==0){
                    Date firstDate = new Date();
                    //考试总时间（秒）
                    long time = (paper.getStarttime().getTime()-firstDate.getTime())/1000+paper.getKstime()*60;
                    if(time<0){
                        responseMap.put("info","考试时间早就过了，你在干嘛呢！");
                    }
                    //插入第一次开始考试时间
                    score.setFirststarttime(firstDate);
                    //设置已经进入过考试
                    score.setState(1);
                    scoreService.updateByPrimaryKeySelective(score);
                    responseMap.put("time",time);
                } else {
                    //考试剩余时间（秒），加上设置的延时
                    long time = (paper.getStarttime().getTime()-new Date().getTime())/1000+paper.getKstime()*60 + score.getDelaytime()*60;
                    if(time<0){
                        if(score.getState()==1){
                            score.setState(3);
                        } else if (score.getState()==2){
                            score.setState(4);
                        }
                        scoreService.updateByPrimaryKeySelective(score);
                        responseMap.put("info","考试时间已经结束！");
                    }
                    responseMap.put("time",time);
                }
            }
            return responseMap;
        } catch (Exception e){
            e.printStackTrace();
            responseMap.put("info",e.getMessage());
            return responseMap;
        }        
    }

    /**
     * 实时保存答案
     * @param paperid
     * @param kgtda
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/saveAnswer")
    public @ResponseBody Map<String,Object> saveAnswer(
            @RequestParam("paperid") Integer paperid,@RequestParam("kgtda") String kgtda,
            HttpServletRequest request,HttpServletResponse response){
        Student student = (Student)request.getSession().getAttribute("student");
        Map<String,Object> responseMap = new HashMap<String, Object>();
        try{
            Paper paper = paperService.selectByPrimaryKey(paperid);
            if(paper.getState()!=2){
                responseMap.put("end",true);
                return responseMap;
            };
            Score score = new Score();
            score.setStuid(student.getId());
            score.setPaperid(paperid);
            if(!(kgtda==null || kgtda.equals(""))){
                score.setKgtda(kgtda);
                Criteria criteria = new Criteria();
                scoreService.updateByPrimaryKeySelective(score);
            }
            score = scoreService.selectByPrimaryKey(score);
            long time = (paper.getStarttime().getTime()-new Date().getTime())/1000+paper.getKstime()*60 + score.getDelaytime()*60;
            if(time<0){
                responseMap.put("end",true);
            }
            responseMap.put("time",time);
            return responseMap;
        } catch (Exception e){
            e.printStackTrace();
            responseMap.put("info","服务器貌似出现错误！");
            return responseMap;
        }
    }

    /**
     * 下载素材文件
     * @param filename
     * @param request
     * @param response
     */
    @RequestMapping(value = "/downloadFile")
    public void downloadFile(@RequestParam("filename") String filename,HttpServletRequest request,HttpServletResponse response){
        try {
            //Student student = (Student)request.getSession().getAttribute("student");
            String filePath = request.getSession().getServletContext().getRealPath("download");
            File file = new File(filePath+"/"+filename);
            // 设置文件名。
            //String outfilename = student.getUsername() + "-" + filename;
            // 设置文件的后缀名。
            //String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("ISO-8859-1");
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("utf-8"),"ISO-8859-1"));
            response.addHeader("Content-Length", "" + buffer.length);
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
            outputStream.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    /**
     * 上传操作题结果
     * @param request
     * @param response
     */
    @RequestMapping(value="/uploadResult",method=RequestMethod.POST)
    public void uploadResult(MultipartHttpServletRequest request,HttpServletResponse response){
        MultipartFile file = request.getFile("file");
        int paperid = Integer.parseInt(request.getParameter("paperid"));
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            if(!file.isEmpty()){
                String fileHz = "";
                if(file.getContentType().equals("application/octet-stream")){
                    fileHz = ".rar";
                } else if(file.getContentType().equals("application/x-zip-compressed")) {
                    fileHz = ".zip";
                } else {
                    out.print("{'info':'暂只能支持.zip和.rar格式的压缩文件'}");
                    return;
                }
                Student student = (Student)request.getSession().getAttribute("student");
                if(student==null){
                    out.print("{'info':'登录超时，请重新登录后再上传！'}");
                    return;
                }
                Paper paper = paperService.selectByPrimaryKey(paperid);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String ksDate = sdf.format(paper.getStarttime());
                //文件上传路径
                String filePath = request.getSession().getServletContext().getRealPath("studentUpload/"+ksDate+"/"+paper.getName()+"/"+student.getClassname());
                File saveFile = new File(filePath+"/"+student.getUsername()+"-"+student.getCardid()+"-"+RealIpUtils.getIpAddr(request)+fileHz);
                FileUtils.writeByteArrayToFile(saveFile, file.getBytes());
                //记入数据库状态，已上传
                Score score = new Score();
                score.setPaperid(paperid);
                score.setStuid(student.getId());
                Score stateScore = scoreService.selectByPrimaryKey(score);
                int state = stateScore.getState();
                if(state == 1){
                    //状态为1，则设置为2，已上传，未交卷
                    score.setState(2);
                    scoreService.updateByPrimaryKeySelective(score);
                } else if(state==3){
                    //状态为3，则设置为4，已上传，已交卷，除上述两种状态，不需进行状态改变
                    score.setState(4);
                    scoreService.updateByPrimaryKeySelective(score);
                }
                out.print("{'success':'上传成功！'}");
            }
        } catch(Exception e) {
            e.printStackTrace();
            out.print("{'info':'服务器太忙了，上传失败！'");
        } finally {
            if(out!=null){
                out.flush();
                out.close();
            }
        }
        return;
    }

    /**
     * 交卷
     * @param paperid
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/end")
    public @ResponseBody Map<String,Object> endKs(@RequestParam("paperid") Integer paperid,
                                        HttpServletRequest request,HttpServletResponse response){
        Student student = (Student)request.getSession().getAttribute("student");
        Map<String,Object> responseMap = new HashMap<String, Object>();
        try{
            Score score = new Score();
            score.setPaperid(paperid);
            score.setStuid(student.getId());

            Score stateScore = scoreService.selectByPrimaryKey(score);
            //状态0为未开始考试，1为已经进入过，2为已上传、未交卷，3为未上传、已交卷，4为已上传、已交卷
            if(stateScore.getState()==2){
                score.setState(4);
            } else {
                responseMap.put("isUpload",false);
                score.setState(3);
            }
            scoreService.updateByPrimaryKeySelective(score);
            responseMap.put("end","交卷成功");
            return responseMap;
        } catch (Exception e){
            e.printStackTrace();
            responseMap.put("info","交卷不太顺利！");
            return responseMap;
        }
    }
}
